Memory Management (ODMemory)
This section describes the OpenDoc memory manager utility, the Mac OS implementation of which resides in the files ODMemory. h and ODMemory.cpp.OpenDoc includes a memory management utility that you can use for allocating and manipulating memory as needed by your parts. On each platform, the OpenDoc memory manager supplements the capabilities of the platform's own memory manager; you can use platform memory manager calls alone, you can use the OpenDoc memory manager alone, or you can use both as needed.
The OpenDoc memory manager is a fast and very space-efficient memory allocator. It is a utility library used by OpenDoc but independent of it. The OpenDoc memory manager's only requirement is that its clients use a procedural shared library mechanism, such as CFM on the Mac OS or DLL on Windows.
The OpenDoc memory manager works with but is not dependent upon SOM. When both are installed, the OpenDoc memory manager takes over the SOM memory management routines; in that case, calls to functions such as
SOMMalloc
andSOMFree
use the OpenDoc memory manager.For a brief introduction to SOM, refer to Appendix B, "System Object Model." For information about the SOM memory manager, see SOMobjects Developer Toolkit Users Guide and SOMobjects Developer Toolkit Programmers Reference Manual from IBM.
Allocating Heaps
A heap is a space in which blocks of memory of arbitrary size can be allocated. All blocks allocated by the OpenDoc memory manager (other than handles) are in one of its heaps. When the OpenDoc memory manager initializes itself, it creates a heap for you; you can create additional heaps if you want to. You can also delete heaps, and deleting a heap with blocks still in it is both legal and faster than deleting all the blocks individually.All storage used by the OpenDoc memory manager originally comes from the operating system's platform-specific memory manager. The OpenDoc memory manager gets memory for its heaps from the platform memory manager in large chunks (typically 32 KB or greater), and then subdivides these chunks as needed to allocate blocks. When a heap runs out of room, the OpenDoc memory manager asks the platform memory manager for another chunk, and when the OpenDoc memory manager frees all blocks in a chunk, it returns the entire chunk to the platform memory manager.
The data type that represents a heap (
MemHeap
) is opaque; no internal structure is visible to you. You refer to heaps using pointers, and you can operate on them only with the OpenDoc memory manager functions.Memory for a heap can come from one of three places:
On non-Mac OS platforms, application and temporary memory may be identical; on the Mac OS, however, temporary memory is important because very little application memory may be available in the fixed-size partition available to an OpenDoc process. For cross-platform code, therefore, it is better to specify temporary memory.
- system memory (shared among all processes on the system)
- application memory (local to the current process or OpenDoc document)
- temporary memory (from a shared pool available to all applications)
These are the principal heap-manipulation functions provided by the OpenDoc memory manager:
Using multiple heaps can be convenient for your part editor, although it is not quite as efficient as storing everything in one heap (because free memory in one heap is not available to another). However, allocating a heap for temporary use and then deleting it when done can help reduce memory fragmentation, since deleting the heap leaves a small number of large free blocks, rather than a large number of small ones.
MMNewHeap
creates a new heap with a given location and initial size (and optionally a name). Whenever the heap runs out of space, it will request more bytes from the platform memory manager.MMDisposeHeap
disposes of a heap, returning to the operating system all the memory it has allocated. As a result, all blocks in the heap, and pointers to those blocks, become invalid.MMGetDefaultHeap
returns a pointer to the current default heap. There is always a default heap; memory allocation calls that don't explicitly specify a heap use the current default heap. (If you use SOM, this includes SOM's memory management calls.)MMSetDefaultHeap
makes a specified heap the default heap. In this way you can change the default heap at any time.
Allocating Nonrelocatable Blocks
Memory within a heap is allocated nonrelocatable blocks. The interface for creating and operating on these blocks is similar to the ANSI C memory API, which is similar to that used by SOM. In fact, the SOM memory calls are rerouted to these routines, so that callingSOMMalloc
, for example, is identical to callingMMAllocate
.These are the principal block-allocation functions provided by the OpenDoc memory manager:
You should clear the is-object flag before freeing any block, because the debugging configuration of the OpenDoc memory manager warns you if you free a block containing an object. SOM objects that inherit from
MMAllocate
allocates a new block of a specified size from the default heap and returns a pointer to it. (The largest block that can be allocated is 0xFFFFFF, or 16 megabytes.)MMAllocateClear
similarly allocates a block but also fills it with zeros.MMAllocateIn
andMMAllocateClearIn
also allocate blocks but let you specify the heap.MMReallocate
changes the size of an already allocated block and returns a pointer to the new location of the block.MMFree
frees (disposes of) a previously allocated block.MMBlockSize
returns the size of a block.MMGetHeap
returns a pointer to the heap that owns a block.MMSetIsObject
sets the is-object flag of a block;MMIsObject
queries the is-object flag. If the flag is set, the OpenDoc memory manager assumes that the block contains a valid SOM object. Some of the memory debugging calls (see "Memory Debugging") make use of this flag; you can also use it for your own purposes.
ODObject
(the OpenDoc root object class) automatically set the is-object flag when created and clear it when deleted.Allocating Relocatable Blocks (Handles)
For convenience, the OpenDoc memory manager also provides operations for allocating relocatable blocks, referenced via handles. These blocks are allocated directly by the platform's memory manager, not by the OpenDoc memory manager, and they don't reside in heaps managed by the OpenDoc memory manager. However, you can still specify the same types of locations.Because relocatable blocks are allocated by the platform's memory manager, an OpenDoc handle (type
MMHandle
) is the same as a platform-specific handle and can be passed to operating system routines that take handles; likewise, a handle allocated by an operating system routine can be passed to any of the OpenDoc memory manager routines that take a parameter of typeMMHandle
.These are the principal handle-allocation functions provided by the OpenDoc memory manager:
MMAllocateHandle
allocates a new relocatable block from the default heap and returns a handle to it;MMAllocateHandleIn
allocates a new relocatable block from a specified heap. The source of the block (system, application, or temporary memory) is that of the indicated heap, even though the block is not actually allocated inside that heap.MMFreeHandle
frees (disposes of) a previously allocated relocatable block.MMCopyHandle
makes an exact copy of a relocatable block and returns a handle to the copy.MMGetHandleSize
returns the size of a relocatable block.MMSetHandleSize
changes the size of a relocatable block.MMLockHandle
locks a relocatable block, which prevents it from being relocated by the operating system in response to other memory requests.MMLockHandle
returns a direct pointer to the contents of the block; you can dereference this pointer to access the block's contents as long as the block is locked.On the Mac OS platform a handle is just a pointer to a pointer to a block, and the data in the block can be accessed at any time by doubly dereferencing the handle. Other platforms, such as Windows, have a more opaque notion of a handle. Therefore, to make your code cross-platform, you should always use the pointer returned by the
MMLockHandle
function instead of dereferencing your handles.MMUnlockHandle
andMMUnlockPtr
unlock a relocatable block, given either a handle to the block or a pointer to its contents.
- IMPORTANT
- Calls to
MMLockHandle
andMMUnlockHandle
do not nest. The first call toMMUnlockHandle
unlocks the block (and invalidates any pointers to its contents) no matter how many timesMMLockHandle
has been called.![]()
Memory Debugging
There are two configurations of the OpenDoc memory manager utility: regular and debugging. During development, if you link with the debugging configuration you can use its extra functions to help debug your code's memory management. These functions allow you to detect whether you are passing illegal values to the OpenDoc memory manager or overwriting heap data outside of blocks. You can also determine whether a given block is valid, and you can collect statistics on a heap as a whole or on all blocks in a heap.Besides providing these extra routines, the debugging configuration also performs more internal checking of function parameters and data structures; this makes it slower but better able to detect problems.
These are the principal debugging functions provided by the debugging configuration of the OpenDoc memory manager:
MMBeginMemValidation
andMMEndMemValidation
turn memory validation on and off. When validation is on, newly allocated blocks are filled with 0xBB ("Born") and freed blocks are filled with 0xDD ("Dead"). Calls that take a block pointer as a parameter verify that the block is valid; if it isn't, they warn you (typically via a low-level debugger) and the operation fails.Memory validation can also be turned on and off via the ODDebug menu in debugging builds of OpenDoc. (In the Mac OS implementation, this is a submenu of the Apple menu.)
Note that you can nest memory-validation calls.
MMBeginHeapChecking
andMMEndHeapChecking
turn heap-checking on and off. Heap-checking includes memory validation, but in addition most OpenDoc memory manager calls scan through their heap to verify that its internal structure is intact and valid. if it isn't, they warn you (typically via a low-level debugger) and the operation fails.Heap checking can be very slow, especially if the heap contains a large number of blocks. Memory-intensive operations such as opening or closing a storage object can take tens of times longer than normal. Nevertheless, heap checking can be the best way to track down obscure bugs that destroy heaps.
Heap checking can also be turned on and off via the ODDebug menu in debugging builds of OpenDoc. (In the Mac OS implementation, this is a submenu of the Apple menu.)
Note that you can nest heap-checking calls.
MMDoesHeapExist
determines whether the given heap is known to the OpenDoc memory manager. If the heap was allocated by another process, you may still be able to manipulate it with the platform-specific memory manager, although that may be bad practice.MMValidatePtr
andMMValidateHandle
validate a single block (normal or relocatable). If the pointer or handle passed in does not reference a valid block, or if the block's heap is corrupted, you are warned via a low-level debugger.MMValidateObject
verifies a block in the same manner asMMValidatePtr
but also verifies that the block's is-object flag is set. It also verifies that the block looks like a valid object to the SOM runtime system.MMValidateHeap
andMMValidateAllHeaps
check either a single heap, or all known heaps, for consistency. This can be a slow operation if there are large numbers of blocks. If a heap is corrupted, you are warned via a low-level debugger.MMGetHeapInfo
returns useful information about a heap, such as its name, its size, the number of free bytes it contains, the number of blocks it contains, and the number of objects (blocks with the is-object flag set) it contains.MMWalkHeap
lets you examine every allocated block in a heap, using a pointer you provide to a callback function that is called once for every block in the heap.
Main | Page One | What's New | Apple Computer, Inc. | Find It | Contact Us | Help